from tkinter import *
from tkinter import scrolledtext

# 创建一个函数用于生成新的Frame
def frame(master, width=20, height=1):
    w = Frame(master)
    w.pack(expand=YES, fill=BOTH)
    return w

# 创建一个函数用于生成按钮并添加命令
def btn(master, text, command):
    w = Button(master, text=text, command=command, width=6)
    w.pack(side=LEFT, expand=YES, fill=BOTH, padx=2, pady=2)
    return w

# 计算表达式并更新历史记录
def calc(text_data, history_text):
    try:
        result = eval(text_data)
        # 记录计算过程和结果
        history_text.insert(END, text_data + " = " + str(result) + "\n")
        return str(result)
    except (SyntaxError, ZeroDivisionError, NameError) as e:
        # 如果有错误，记录错误信息
        history_text.insert(END, "错误: " + str(e) + "\n")
        return 'Error'

# 回退一个字符，如果当前没有输入数字或为空则不执行回退
def back(text_data):
    if len(text_data) > 0 and text_data[-1].isdigit() or text_data[-1] == '.':
        return text_data[:-1]
    return text_data

# 初始化计算器界面
init_root = Tk()
init_root.title("计算器")
init_root.geometry("500x600")  # 设置窗口大小

# 创建菜单
main_menus = Menu(init_root)
calc_menu = Menu(main_menus, tearoff=0)
calc_menu.add_command(label='退出', command=init_root.quit)
main_menus.add_cascade(label='菜单', menu=calc_menu)
init_root.config(menu=main_menus)

# 创建输入框和分隔符标志
text = StringVar()
separator_flag = IntVar()
separator_flag.set(0)

# 创建历史记录文本框
history_text = scrolledtext.ScrolledText(init_root, width=50, height=10)
history_text.pack(expand=YES, fill=BOTH, padx=2, pady=4)
history_text.insert(END, "计算历史:\n")

# 创建输入框
Entry(init_root, textvariable=text, width=50).pack(expand=YES, fill=BOTH, padx=2, pady=4)

# 创建第一行按钮
first_line = frame(init_root)
btn(first_line, '回退', lambda t=text: t.set(back(t.get())))  # 回退按钮
btn(first_line, '清空', lambda t=text: t.set(''))  # 清空按钮

# 创建其他按钮
for key in ('789/', '456*', '123-', '0.=+'):
    others = frame(init_root)
    for char in key:
        if char == '=':
            # 等于按钮，执行计算
            btn(others, char, lambda data=text, h=history_text: data.set(calc(data.get(), h)))
        else:
            # 数字和运算符按钮，添加字符
            btn(others, char, lambda data=text, c=char: data.set(data.get() + c))

# 运行主事件循环
init_root.mainloop()